#include "utils.h"

namespace libxcom {
std::string trim(std::string str)
{
    // 去掉前面的空格
    str.erase(str.begin(),
              std::find_if_not(str.begin(), str.end(), [](int ch) { return std::isspace(ch); }));

    // 去掉后面的空格
    str.erase(std::find_if(str.rbegin(), str.rend(), [](int ch) { return !std::isspace(ch); }).base(),
              str.end());

    return str;
}

unsigned char CharToBcd(char h, char l)
{
    if (h < '0' || h > '9' || l < '0' || l > '9') {
        throw std::invalid_argument("Input character is not a digit");
    }
    return ((h - '0') << 4) | (l - '0');
}

std::vector<unsigned char> StringToBcd(const std::string &str)
{
    std::string trimStr = trim(str);
    std::vector<unsigned char> bcd;
    for (size_t i = 0; i < trimStr.length(); i += 2) {
        bcd.push_back(CharToBcd(trimStr[i], i + 1 < trimStr.length() ? trimStr[i + 1] : '0'));
    }
    return bcd;
}

CmdValue VectorToCmd(const std::vector<uint8_t> &vec, bool reverse)
{
    libxcom::CmdValue result;
    if (reverse == false) {
        for (auto &c : vec) {
            result += c;
        }
    } else {
        std::for_each(vec.rbegin(), vec.rend(), [&](uint8_t v) { result += v; });
    }
    return result;
}

std::string BcdToChar(unsigned char bcd)
{
    std::ostringstream oss;
    oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(bcd);
    return oss.str();
}

std::string BcdToString(const CmdValue &bcd)
{
    std::string str;
    for (int i = 0; i < bcd.Length(); i++) {
        str += BcdToChar(bcd[i]);
    }
    return str;
}

} // namespace libxcom
